﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace TemplateEngineWithChart.Docx.Processors.ProcessResults
{
    internal class Prototype
    {
        private readonly ProcessContext _context;
        /// <summary>
        /// Creates prototype from list of prototype items.
        /// </summary>
        /// <param name="context">Process context.</param>
        /// <param name="prototypeItems">List of prototype items.</param>
        private Prototype(ProcessContext context, IEnumerable<XElement> prototypeItems)
        {
            _context = context;
            PrototypeItems = prototypeItems.ToList();
        }

        /// <summary>
        /// Creates prototype from list content control and fieldNames.
        /// </summary>
        /// <param name="context">Process context.</param>
        /// <param name="listContentControl">List content control element.</param>
        /// <param name="fieldNames">Names of fields with content.</param>
        public Prototype(ProcessContext context, XElement listContentControl, IEnumerable<string> fieldNames)
        {
            _context = context;
            if (listContentControl.Name != W.sdt)
                throw new Exception("List content control is not a content control element");

            fieldNames = fieldNames.ToList();

            // All elements inside list control content are included to the prototype.
            var listItems = listContentControl
                .Element(W.sdtContent)
                .Elements()
                .ToList();

            //var tagsInPrototype = listItems.DescendantsAndSelf(W.sdt)
            //    .Select(sdt => sdt.SdtTagName());

            //// If any field not found return empty list.
            //if (fieldNames.Any(fn => !tagsInPrototype.Contains(fn)))
            //{
            //    IsValid = false;
            //    return;
            //}

            IsValid = true;
            PrototypeItems = listItems;
        }

        public bool IsValid { get; private set; }
        public List<XElement> PrototypeItems { get; private set; }

        public Prototype Clone()
        {
            return new Prototype(_context, PrototypeItems.ToList());
        }

        public Prototype Exclude(LevelPrototype prototypeForExclude)
        {
            return new Prototype(_context, PrototypeItems
                .Where(itemPrototype => !prototypeForExclude
                    .PrototypeItems
                    .Contains(itemPrototype)));
        }

        /// <summary>
        /// Retrieves prototype for current content item.
        /// </summary>
        /// <param name="fieldNames">Fields names for current content item.</param>
        /// <returns>Prototype for current content item.</returns>
        public LevelPrototype CurrentLevelPrototype(IEnumerable<string> fieldNames)
        {
            return new LevelPrototype(_context, PrototypeItems, fieldNames);
        }
    }
}
